﻿#include <Sys\RenderUnit\SysRenderDatagram\CONTROLATTRIBRD.HPP>

#define CControlAttrib_ClassID L"DF7A16EF47D447138E1973D4769AA503"

using namespace CxxlMan;
using namespace Cxxl3D;

cxxlObject *cxxlFASTCALL New_CControlAttribRD();
cxxlPreserve2 *cxxlFASTCALL Regenera_CControlAttribRD(const wchar_t *ClassID);

class CControlAttribRD:public IControlAttribRD
{
  bool m_isModified;

  struct tagAttr 
  {
    char m_bCull:2;    // 正反面剔除模式 0:無所謂  1:剔除順時鐘面  -1:剔除反時鐘面 -2:不剔除
    char m_bFill:2;    // 多邊形填充模式 0:無所謂  1:畫面  -1:畫線 -2:畫點
    char m_bShadeMode:2;    // 是否使用內插(GL_SMOOTH)  0:無所謂 1:是  -1:否
    char m_bAutoNormalize:1; // 是否為 Normalize 做正規化處理 1:是  0:否

    //char m_bMipmapMode:2;   // 貼圖的 Mipmap 模式  2:None 1:Bilinear -1:Trilinear -2:Anisotropic filter
    // char m_bTextureAddrMode:3; // 設定貼圖座標模式  0:無所謂 2:Repeat 1:Mirror -1:ClampEdge -2:ClampBorder
    /*
    union
    {
      struct 
      {
        char R,G,B,A;
      };
      unsigned int Color;
    }m_TextureClampBorderColor; // TextureAddrMode() 指定為 ClampBorder 時，所用的顏色
    */
  }Attr;

  // 比對各屬性，不符就呼叫 IControlAttrib_CEO，由 Render 單元叫用
  virtual void cxxlFASTCALL Chk(const CxxlMan::Smart_Ptr<IControlAttribRD> &IControlRD_Arg, IControlAttrib_CEO *IControlAttrib_CEO_Arg)
  {
    CControlAttribRD *pSrc = (CControlAttribRD *)IControlAttribRD::GetImp(IControlRD_Arg);

    pSrc->csPreserve.Enter();
    tagAttr SrcAttr = pSrc->Attr;
    pSrc->csPreserve.Leave();

    csPreserve.Enter();
    tagAttr ThisAttr = Attr;
    csPreserve.Leave();

    // 正反面剔除模式
    if(SrcAttr.m_bCull != 0 && SrcAttr.m_bCull != ThisAttr.m_bCull)
      IControlAttrib_CEO_Arg->Cull( SrcAttr.m_bCull );

    // 多邊形填充模式
    if(SrcAttr.m_bFill != 0 && SrcAttr.m_bFill != ThisAttr.m_bFill)
      IControlAttrib_CEO_Arg->Fill( SrcAttr.m_bFill );

    // 內插模式
    if(SrcAttr.m_bShadeMode != 0 && SrcAttr.m_bShadeMode != ThisAttr.m_bShadeMode)
      IControlAttrib_CEO_Arg->ShadeModel( SrcAttr.m_bShadeMode > 0 );

    // 設定貼圖座標模式
    // if(SrcAttr.m_bTextureAddrMode != 0 && SrcAttr.m_bTextureAddrMode != ThisAttr.m_bTextureAddrMode)
    //  IControlAttrib_CEO_Arg->TextureAddrMode( SrcAttr.m_bTextureAddrMode );

    // ClampBorder 時所用的顏色
    //if(SrcAttr.m_TextureClampBorderColor.Color != ThisAttr.m_TextureClampBorderColor.Color)
    //  IControlAttrib_CEO_Arg->TextureClampBorderColor( SrcAttr.m_TextureClampBorderColor.R, SrcAttr.m_TextureClampBorderColor.G, SrcAttr.m_TextureClampBorderColor.B, SrcAttr.m_TextureClampBorderColor.A );

    // 貼圖的 Mipmap 模式
    //if(SrcAttr.m_bMipmapMode != 0 && SrcAttr.m_bMipmapMode != ThisAttr.m_bMipmapMode)
    //  IControlAttrib_CEO_Arg->TextureMipmapMode( SrcAttr.m_bMipmapMode );

    // AutoNormalize
    if(SrcAttr.m_bAutoNormalize != ThisAttr.m_bAutoNormalize)
      IControlAttrib_CEO_Arg->AutoNormalize(SrcAttr.m_bAutoNormalize);


  }

  // 由 Render 單元叫用，設定所有屬性
  virtual void cxxlFASTCALL SetAll(IControlAttrib_CEO *IControlAttrib_CEO_Arg)
  {
    csPreserve.Enter();
    tagAttr ThisAttr = Attr;
    csPreserve.Leave();

    // 正反面剔除模式
    if(ThisAttr.m_bCull != 0)
      IControlAttrib_CEO_Arg->Cull( ThisAttr.m_bCull );

    // 多邊形填充模式
    if(ThisAttr.m_bFill != 0)
      IControlAttrib_CEO_Arg->Fill( ThisAttr.m_bFill );

    // 內插模式
    if(ThisAttr.m_bShadeMode != 0)
      IControlAttrib_CEO_Arg->ShadeModel( ThisAttr.m_bShadeMode > 0);

    // 設定貼圖座標模式
    // if(ThisAttr.m_bTextureAddrMode != 0)
    //  IControlAttrib_CEO_Arg->TextureAddrMode( ThisAttr.m_bTextureAddrMode );

    // ClampBorder 時所用的顏色
    // IControlAttrib_CEO_Arg->TextureClampBorderColor( ThisAttr.m_TextureClampBorderColor.R, ThisAttr.m_TextureClampBorderColor.G, ThisAttr.m_TextureClampBorderColor.B, ThisAttr.m_TextureClampBorderColor.A );

    // 貼圖的 Mipmap 模式
    //if(ThisAttr.m_bMipmapMode != 0)
    //  IControlAttrib_CEO_Arg->TextureMipmapMode( ThisAttr.m_bMipmapMode );

    // AutoNormalize
    IControlAttrib_CEO_Arg->AutoNormalize(ThisAttr.m_bAutoNormalize);

  }

  // 由 Render 單元叫用，並恢復設定為 false
  virtual bool cxxlFASTCALL isModified()
  {
    CriticalSecHandle AutoCSH(csPreserve);

    bool vIsModified = m_isModified;
    m_isModified = false;

    return vIsModified;
  }


  // 正反面剔除模式 CullMode = 0:無所謂  1:剔除順時鐘面  -1:剔除反時鐘面  -2:不剔除
  virtual void cxxlFASTCALL Cull(char CullMode)
  {
    csPreserve.Enter();
    Attr.m_bCull = CullMode;
    m_isModified = true;
    csPreserve.Leave();
  }

  // 多邊形填充模式 0:無所謂  1:畫面  -1:畫線 -2:畫點
  virtual void cxxlFASTCALL Fill(char FillMode)
  {
    csPreserve.Enter();
    Attr.m_bFill = FillMode;
    m_isModified = true;
    csPreserve.Leave();
  }

  // 設定貼圖座標模式 Mode = 0:無所謂 2:Repeat 1:Mirror -1:ClampEdge -2:ClampBorder
  //virtual void TextureAddrMode(char Mode)
  //{
  //  csPreserve.Enter();
  //  Attr.m_bTextureAddrMode = Mode;
  //  m_isModified = true;
  //  csPreserve.Leave();
  //}

  // TextureAddrMode() 指定為 ClampBorder 時，所用的顏色，內定為 0,0,0,0
  //virtual void TextureClampBorderColor(char R, char G, char B, char A)
  //{
  //  csPreserve.Enter();
  //  Attr.m_TextureClampBorderColor.R = R;
  //  Attr.m_TextureClampBorderColor.G = G;
  //  Attr.m_TextureClampBorderColor.B = B;
  //  Attr.m_TextureClampBorderColor.A = A;
  //  m_isModified = true;
  //  csPreserve.Leave();
  //}

  // 貼圖的 Mipmap 模式 Mode = 0:無所謂 2:None 1:Bilinear -1:Trilinear -2:Anisotropic filter
  //virtual void TextureMipmapMode(char Mode)
  //{
  //  csPreserve.Enter();
  //  Attr.m_bMipmapMode = Mode;
  //  m_isModified = true;
  //  csPreserve.Leave();
  //}

  // 是否為 Normalize 做正規化處理
  // Switch = true:是  false:否
  virtual void cxxlFASTCALL AutoNormalize(bool Switch)
  {
    csPreserve.Enter();
    Attr.m_bAutoNormalize = Switch;
    m_isModified = true;
    csPreserve.Leave();
  }

  // 是否使用內插(GL_SMOOTH) ShadeMode = 0:無所謂  1:是  -1:否
  virtual void cxxlFASTCALL ShadeModel(char ShadeMode)
  {
    csPreserve.Enter();
    Attr.m_bShadeMode = ShadeMode;
    m_isModified = true;
    csPreserve.Leave();
  }

  virtual void *cxxlFASTCALL GetImp()
  {
    return this;
  }

protected:
  // 儲存容器藉此取得要永續存取的屬性資料
  // 延伸類別須以 virtual 的形式覆寫
  // 並且須呼叫上層類別的此函數
  virtual bool cxxlFASTCALL Ref(Filter *F)
  {
    if(F != NULL && IControlAttribRD::Ref(F))
    {
      if(F->Ref((char *)&Attr,sizeof(Attr),L"CtrlATTR") == false) 
        return false;

      LoadFilter *pLoadFilter = dynamic_cast<LoadFilter*>(F);
      if(pLoadFilter && pLoadFilter->isChk() == false)      
        m_isModified = true;

      return true;
    }
    else
      return false;
  }


public:
  // Constructor
  CControlAttribRD()
    :cxxlObject(CxxlMan::Spirit_Easy),    
    cxxlPreserve2(CControlAttrib_ClassID) // 在建構時指定 ClassID    
  {
    memset(&Attr,0,sizeof(Attr));
    m_isModified = true;
  }
  virtual ~CControlAttribRD()
  {
  }

  friend cxxlObject *cxxlFASTCALL New_CControlAttribRD();
  friend cxxlPreserve2 *cxxlFASTCALL Regenera_CControlAttribRD(const wchar_t *ClassID);

};

cxxlObject *cxxlFASTCALL New_CControlAttribRD()
{
  return new CControlAttribRD();
}

cxxlPreserve2 *cxxlFASTCALL Regenera_CControlAttribRD(const wchar_t *ClassID)
{
  if(wcscmp(CControlAttrib_ClassID, ClassID) == 0)
    return new CControlAttribRD;
  else
    return NULL;

}
